package test.XML;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import test.Issue.Issue;

public class Xpath {
	public static List<Issue> getPriorityIssuesToProcess(InputStream input, boolean onlyPriority)
			throws ParserConfigurationException, SAXException, IOException {

		List<Issue> priorityIssues = new ArrayList<Issue>();
		List<Issue> issues;
		try {
			issues = getIssues(input);
			
			if (!onlyPriority) {
				return issues;
			}

			for (Issue issue : issues) {
				if (issue.shouldProcess()) {
					priorityIssues.add(issue);
				}
			}			
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return priorityIssues;

	}

	public static List<Issue> getIssues(InputStream input)
			throws ParserConfigurationException, SAXException, IOException,
			XPathExpressionException {
		List<Issue> issues;

		DocumentBuilderFactory domFactory = DocumentBuilderFactory
				.newInstance();
		domFactory.setNamespaceAware(true);
		DocumentBuilder builder = domFactory.newDocumentBuilder();

		Document doc = builder.parse(input);
		XPath xpath = XPathFactory.newInstance().newXPath();
		xpath.setNamespaceContext(new PersonalNamespaceContext());

		XPathExpression exprId = xpath
				.compile("/pre:html/pre:body//pre:table[@id='issuetable']//pre:td[@class='nav issuekey']/pre:a/text()");
		List<String> issueIdList = runXpath(doc, exprId);
		XPathExpression exprPriority = xpath
				.compile("/pre:html/pre:body//pre:table[@id='issuetable']//pre:td[@class='nav priority']/pre:img/@title");
		List<String> issuePriorityList = runXpath(doc, exprPriority);
		XPathExpression exprAssignee = xpath
				.compile("/pre:html/pre:body//pre:table[@id='issuetable']//pre:td[@class='nav assignee']/pre:span/pre:a/text()");
		List<String> issueAssigneeList = runXpath(doc, exprAssignee);
		XPathExpression exprStatus = xpath
				.compile("/pre:html/pre:body//pre:table[@id='issuetable']//pre:td[@class='nav status']/text()");
		List<String> issueStatusList = runXpath(doc, exprStatus);

		issues = createIssueList(issueIdList, issuePriorityList,
				issueAssigneeList, issueStatusList);

		return issues;
	}

	private static List<Issue> createIssueList(List<String> issueIdList,
			List<String> issuePriorityList, List<String> issueAssigneeList,
			List<String> issueStatusList) {
		List<Issue> issueList = new ArrayList<Issue>();
		String id;
		int priority;
		String assignee;
		String status;

		for (int i = 0; i < issueIdList.size() - 1; i++) {
			id = issueIdList.get(i).trim();
			priority = Integer.parseInt(issuePriorityList.get(i).substring(0, 1));
			assignee = issueAssigneeList.get(i).replaceAll("\\n", " ").trim();
			status = issueStatusList.get(i).trim();

			Issue issue = new Issue(id, priority, assignee, status);

			issueList.add(issue);
		}
		return issueList;
	}

	private static List<String> runXpath(Document doc, XPathExpression expr) {
		Object result;
		try {
			List<String> resultList = new ArrayList<String>();
			result = expr.evaluate(doc, XPathConstants.NODESET);
			NodeList nodes = (NodeList) result;

			for (int i = 0; i < nodes.getLength(); i++) {
				resultList.add(nodes.item(i).getNodeValue());
				//System.out.println(nodes.item(i).getNodeValue());
			}

			return resultList;
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}
